﻿using System;
using System.Xml;
using Notoric.Model.Internal;
using Notoric.Model.Packaging;
using Notoric.Model.Validation;

namespace Notoric.Model.Elements
{
    /// <summary>
    /// Represents a legato.
    /// </summary>
    /// <remarks>
    /// <para>
    /// The <see cref="LegatoElement"/> is a horizontal <see cref="ConnectorElement"/>.
    /// It connects symbols at different beats and indicates that they should be played legato.
    /// </para>
    /// <para>
    /// The Italian word legato (literally meaning "tied together") indicates that musical notes 
    /// are played or sung smoothly and connected. That is, in transitioning from note to note, 
    /// there should be no intervening silence. Legato technique is required for slurred performance, 
    /// but unlike slurring (as that term is interpreted for some instruments), legato does not forbid 
    /// rearticulation. In standard notation legato is indicated either with the word legato itself, 
    /// or by a slur (a curved line) under the notes that are to be joined in one legato group. 
    /// Legato, like staccato, is a kind of articulation. There is an intermediate articulation 
    /// called either mezzo staccato or non-legato.
    /// </para>
    /// </remarks>
    public class LegatoElement : ConnectorElement
    {
        #region Constructors

        /// <summary>
        /// Creates a new <see cref="LegatoElement"/> instance.
        /// </summary>
        /// <param name="packagePart">
        /// <para>
        /// Type: <see cref="CompositionPart"/>
        /// </para>
        /// <para>
        /// The package part that owns this element.
        /// </para>
        /// </param>
        /// <param name="owner">
        /// <para>
        /// Type: <see cref="CompositionElement"/>
        /// </para>
        /// <para>
        /// The composition that directly owns this element.
        /// </para>
        /// </param>
        /// <param name="start">
        /// <para>
        /// Type: <see cref="DurationalSymbolElement"/>
        /// </para>
        /// <para>
        /// The durational symbol at which the legato starts.
        /// </para>
        /// </param>
        /// <param name="end">
        /// <para>
        /// Type: <see cref="DurationalSymbolElement"/>
        /// </para>
        /// <para>
        /// The durational symbol at which the legato ends.
        /// </para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="packagePart"/> or <paramref name="owner"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ValidationException">
        /// The <paramref name="start"/> or <paramref name="end"/> is not valid.
        /// </exception>
        public LegatoElement(CompositionPart packagePart, CompositionElement owner, DurationalSymbolElement start, DurationalSymbolElement end)
            : base(packagePart, owner, start, end)
        {
            
        }

        /// <summary>
        /// Creates a new <see cref="LegatoElement"/> instance.
        /// </summary>
        /// <param name="packagePart">
        /// <para>
        /// Type: <see cref="CompositionPart"/>
        /// </para>
        /// <para>
        /// The package part that owns this element.
        /// </para>
        /// </param>
        /// <param name="owner">
        /// <para>
        /// Type: <see cref="CompositionElement"/>
        /// </para>
        /// <para>
        /// The model element that directly owns this element.
        /// </para>
        /// </param>
        /// <param name="element">
        /// <para>
        /// Type: <see cref="XmlElement"/>
        /// </para>
        /// <para>
        /// The XML element that holds the data of this object.
        /// </para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Any of the arguments is <see langword="null"/>.
        /// </exception>
        internal LegatoElement(CompositionPart packagePart, CompositionElement owner, XmlElement element)
            : base(packagePart, owner, element)
        {
            
        }

        #endregion

        #region ConnectorElement Members

        /// <inheritdoc/>
        protected override XmlElement CreateSymbolElement(XmlDocument document)
        {
            return document.CreateElement(
                PackageVocabulary.PackageNamespacePrefix,
                PackageVocabulary.LegatoElementName,
                PackageVocabulary.PackageNamespaceUri
                );
        }

        #endregion
    }
}
